package com.xinzhi.service.impl;

import com.xinzhi.pojo.CustomException;
import com.xinzhi.utlis.Result;
import com.xinzhi.mapper.UserMapper;
import com.xinzhi.pojo.User;
import com.xinzhi.service.IUserService;
import com.xinzhi.utlis.RegUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;


@Service
public class IUserSeviceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private SpringUserDetailsService springUserDetailsService;

    /**
     * 注册
     * @param phonenumber
     * @param password
     * @return
     */
    @Override
    public Result  insert(String phonenumber, String password) {
        if (phonenumber!=null&&phonenumber!=" "){
            boolean check = RegUtils.check(phonenumber, "/^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/");
            if (check){
                return Result.error("手机号格式错误");
            }
        }else {
            return Result.error("手机号不能为空");
        }
        //是否注册过
        String user1 = userMapper.findUserByUser(phonenumber);
        if (user1 != null){
            return Result.error("用户名已存在,请重新输入");
        }
        //输入密码
        if (password ==null && password == " "){
            return Result.error("密码不能为空");
        }
        boolean checkpassword = RegUtils.check(password, "/^[A-Za-z0-9]+$/");
        if (checkpassword){
            return Result.error("密码格式不正确");
        }
        //对密码Security加密
        String encode = passwordEncoder.encode(password);
        //插入数据库
        int insert = userMapper.insert(phonenumber,encode);
        return insert>0 ? Result.ok("注册成功"): Result.error("注册失败");
    }

    /**
     * 发送验证码
     * @param phonenumber
     * @param templateCode
     * @param code
     * @return
     */
    @Override
    public boolean send(String phonenumber, String templateCode, String code) {
        try {
            /* 必要步骤：
             * 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey。
             * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
             * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
             * 以免泄露密钥对危及你的财产安全。
             * SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi */
            Credential cred = new Credential("AKIDyqZT3Ypw1xgMvJYfeYJxUu86qtjMoAG7", "qcEmEbprjzGUWN0d5J9oHWaS6Xpvytb9");

            // 实例化一个http选项，可选，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            // 设置代理（无需要直接忽略）
            // httpProfile.setProxyHost("真实代理ip");
            // httpProfile.setProxyPort(真实代理端口);
            /* SDK默认使用POST方法。
             * 如果你一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
            httpProfile.setReqMethod("POST");
            /* SDK有默认的超时时间，非必要请不要进行调整
             * 如有需要请在代码中查阅以获取最新的默认值 */
            httpProfile.setConnTimeout(60);
            /* 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
            httpProfile.setEndpoint("sms.tencentcloudapi.com");

            /* 非必要步骤:
             * 实例化一个客户端配置对象，可以指定超时时间等配置 */
            ClientProfile clientProfile = new ClientProfile();
            /* SDK默认用TC3-HMAC-SHA256进行签名
             * 非必要请不要修改这个字段 */
            clientProfile.setSignMethod("HmacSHA256");
            clientProfile.setHttpProfile(httpProfile);
            /* 实例化要请求产品(以sms为例)的client对象
             * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
            SmsClient client = new SmsClient(cred, "ap-guangzhou",clientProfile);
            /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
             * 属性可能是基本类型，也可能引用了另一个数据结构
             * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
            SendSmsRequest req = new SendSmsRequest();
            /* 填充请求参数,这里request对象的成员变量即对应接口的入参
             * 短信控制台: https://console.cloud.tencent.com/smsv2
             * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
            /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
            // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
            String sdkAppId = "1400858973";
            req.setSmsSdkAppId(sdkAppId);
            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
            // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
            String signName = "onemakeLove网";
            req.setSignName(signName);
            /* 模板 ID: 必须填写已审核通过的模板 ID */
            // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
            String templateId = templateCode;
            req.setTemplateId(templateId);
            /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
            String[] templateParamSet = {code};
            req.setTemplateParamSet(templateParamSet);
            /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
            String[] phoneNumberSet = {"+86"+phonenumber};
            req.setPhoneNumberSet(phoneNumberSet);
            /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
            SendSmsResponse res = client.SendSms(req);
            // 输出json格式的字符串回包
            System.out.println(SendSmsResponse.toJsonString(res));
            return true;
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 验证码登录
     * @param phonenumber
     * @param password
     * @return
     */
    @Override
    public Result logincode(String phonenumber,String password) {
        if (StringUtils.isNotEmpty(phonenumber) && phonenumber!=" "){
            boolean check = RegUtils.check(phonenumber, "/^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/");
            if (check){
                return Result.error("手机号格式错误");
            }
        }else {
            return Result.error("手机号不能为空");
        }
        //是否注册过
        String user2 = userMapper.findUserByUser(phonenumber);
        if (user2 == null){
            //自动给用户注册
            int insert = userMapper.insert(phonenumber,password);
//            //存储手机号到session
//            session.setAttribute("phonenumber",phonenumber+"");
//            System.out.println("----------"+session.getAttribute("phonenumber"));

            return insert>0 ? Result.ok("登陆成功"):Result.error("登陆失败");
        }
        if (passwordEncoder.matches(password,user2)){
//            //存储手机号到session
//            session.setAttribute("phonenumber",phonenumber+"");
//            return Result.ok("登陆成功");
            try {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phonenumber,password);
                Authentication authentication = authenticationManager.authenticate(authenticationToken);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }catch (AuthenticationException e){
                //认证失败，抛出异常信息
                throw new CustomException(500,e.getMessage());
            }
            User userDetails = (User) springUserDetailsService.loadUserByUsername(phonenumber);
            return Result.ok(userDetails);
        }
        return Result.error("密码错误");
    }

    /**
     * 密码登录
     * @param phonenumber
     * @param password
     * @return
     */
    @Override
    public Result loginpassword(String phonenumber, String password) {
        if (StringUtils.isNotEmpty(phonenumber) && phonenumber!=" "){
            boolean check = RegUtils.check(phonenumber, "/^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/");
            if (check){
                return Result.error("手机号格式错误");
            }
        }else {
            return Result.error("手机号不能为空");
        }
        if (password != null && password != "") {
            boolean check = RegUtils.check(password, "/^[A-Za-z0-9]+$/");
            if (check) {
                return Result.error("密码格式不正确");
            }
        } else {
            return Result.error("密码不能为空");
        }
        String user2 = userMapper.findUserByUser(phonenumber);
        if (user2 == null){
            return Result.ok("您没有账号,请先注册");
        }
        //认证
        if (passwordEncoder.matches(password,user2)){
            try {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phonenumber, password);
                Authentication authentication = authenticationManager.authenticate(authenticationToken);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }catch (AuthenticationException e){
                //认证失败，抛出异常信息
                throw new CustomException(500, e.getMessage());
            }
            User userDetails = (User) springUserDetailsService.loadUserByUsername(phonenumber);
            return Result.ok(userDetails);
        }
        return Result.error("密码不正确");
    }

    /**
     * 忘记密码
     * @param phonenumber
     * @param onepassword
     * @param twopassword
     * @return
     */
    @Override
    public Result forgetpassword(String phonenumber,String onepassword,String twopassword) {
        if (phonenumber!=null&&phonenumber!=" "){
            boolean check = RegUtils.check(phonenumber, "/^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/");
            if (check){
                return Result.error("手机号格式错误");
            }
        }else {
            return Result.error("手机号不能为空");
        }
        //输入密码
        if (onepassword ==null && onepassword == " " && twopassword ==null && twopassword == " "){
            return Result.error("密码不能为空");
        }
        boolean checkpassword = RegUtils.check(onepassword, "^[A-Za-z][0-9]+$");
        boolean checkpassword1 = RegUtils.check(twopassword, "^[A-Za-z][0-9]+$");
        if (checkpassword && checkpassword1){
            return Result.error("密码格式不正确");
        }
        if (!onepassword.equals(twopassword)){
            return Result.error("两次密码不一致，请重新输入");
        }
        String encode = passwordEncoder.encode(onepassword);
        userMapper.updatepassword(phonenumber,encode);
        return Result.ok("修改密码成功");
    }

    /**
     * 修改密码
     * @param user
     * @param session
     * @return
     */
    @Override
    public Result updatepassword(User user,HttpSession session) {
        Object attribute = session.getAttribute("phonenumber");
        System.out.println(attribute);
//        String phonenumber = user.getPhonenumber();
        //拿到手机号
        String phonenumber = attribute.toString();
        //用户输入的原密码
        String password = user.getPassword();
        //第一次密码
        String onepassword = user.getOnepassword();
        //第二次密码
        String twopassword = user.getTwopassword();
        //判断原密码，第一次密码，第二次密码是否为空等其他的判断条件
        if (onepassword ==null && onepassword == " " && twopassword ==null && twopassword == " " && password ==null && password == " "){
            return Result.error("密码不能为空");
        }
        boolean checkpassword = RegUtils.check(password, "^[A-Za-z][0-9]+$");
        boolean checkpassword1 = RegUtils.check(onepassword, "^[A-Za-z][0-9]+$");
        boolean checkpassword2 = RegUtils.check(twopassword, "^[A-Za-z][0-9]+$");
        if (!checkpassword && !checkpassword1 && checkpassword2){
            return Result.error("密码格式不正确");
        }
        if (!onepassword.equals(twopassword)){
            return Result.error("两次密码不一致，请重新输入");
        }
        System.out.println(phonenumber);
        //查找数据库中的密码
        String sqlpassword = userMapper.findUserByUser(phonenumber);
        //用户输入的密码和库中密码对比
        if (passwordEncoder.matches(password,sqlpassword)){
            String encode = passwordEncoder.encode(onepassword);
            userMapper.updatepassword(phonenumber,encode);
            return Result.ok("修改成功");
        }
        return Result.error("原密码错误");
    }
}
